package com.yupi.springbootinit.sse;

import com.yupi.springbootinit.common.BaseResponse;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.common.ResultUtils;
import com.yupi.springbootinit.exception.BusinessException;
import com.yupi.springbootinit.exception.ThrowUtils;
import com.yupi.springbootinit.model.entity.Chart;
import com.yupi.springbootinit.model.enums.ChartStatusEnum;
import com.yupi.springbootinit.service.ChartService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;

@RestController
@RequestMapping("/sse")
@Slf4j
public class SseController {

    @Resource
    SseService sseService;
    @Resource
    ChartService chartService;

    /**
     * 检查图表状态次数
     */
    public static final int CHECK_CHART_STATUS_NUM = 5;
    /**
     * 检查图表状态间隔时间
     */
    public static final int CHECK_CHART_STATUS_INTERNAL_TIME = 1500;

    /**
     * 时候sse获取图表生成状态
     *
     * @param id
     * @return
     */
    @GetMapping(path = "/getChartStatus/{id}")
    public SseEmitter sseEmitter(@PathVariable("id") String id) {
        ThrowUtils.throwIf(id == null, ErrorCode.PARAMS_ERROR, "id不能为空");
        SseEmitter sseEmitter = sseService.getConn(id);
        try {
            sseEmitter.send(SseEmitter.event().comment("id：" + id + " 已经连接"));
        } catch (IOException e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "sse发送消息失败");
        }
        CompletableFuture.runAsync(() -> {
            for (int i = 0; i < CHECK_CHART_STATUS_NUM; i++) {//最多查5次 每次间隔1.5秒
                try {
                    Chart chart = chartService.getById(id);
                    if (chart != null) {
                        String status = chart.getStatus();
                        log.info("status   :{}", status);
                        String succeed = ChartStatusEnum.SUCCEED.status;
                        String failed = ChartStatusEnum.FAILED.status;
                        sseEmitter.send(status);
                        if (succeed.equalsIgnoreCase(status) || failed.equalsIgnoreCase(status)) {
                            sseEmitter.complete();
                            break;
                        }
                    }
                    Thread.sleep(CHECK_CHART_STATUS_INTERNAL_TIME);
                } catch (Exception e) {
                    throw new BusinessException(ErrorCode.SYSTEM_ERROR, "sse发送消息失败");
                }
            }
        });
        return sseEmitter;
    }


    /**
     * 客户端向服务端发起sse连接
     * @param id
     * @return
     */
    @GetMapping("/subscribeSse/{id}")
    public SseEmitter subscribeSse(@PathVariable("id") String id) {
        SseEmitter sseEmitter = sseService.getConn(id);
        try {
            sseEmitter.send(SseEmitter.event().comment("id：" + id + " 已经连接"));
        } catch (IOException e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "sse发送消息失败");
        }
        return sseEmitter;

    }

    /**
     * 发布消息
     * @param id
     * @param content
     * @return
     */
    @GetMapping("/publish/{id}")
    public BaseResponse<String> publish(@PathVariable("id") String id, @RequestParam("content") String content) {
        sseService.sendMessage(id, content);
        return ResultUtils.success("消息推送成功");
    }

    /**
     * 关闭sse连接
     * @param id
     * @return
     */
    @GetMapping("/close/{id}")
    public BaseResponse<String> close(@PathVariable("id") String id) {
        SseEmitter sseEmitter = sseService.getSseEmitterPool().get(id);
        if (sseEmitter == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "要关闭的sse不存在");
        }
        sseEmitter.complete();
        return ResultUtils.success("sse关闭成功");
    }


}
